class: inverse,left, middle background-image: url(data:image/png;base64,#background.png) background-size: cover <img src="data:image/png;base64,#LOGO_DIPLOMADO.png" width="500px"/> ##Módulo 1: Manipulación y Análisis de Datos Geoespaciales ###R como SIG: Visualización de geodatos en R. Gabriel Castro B. <br> <a href="http://github.com/JoseLastra"> mail: gabriel.castro.b@pucv.cl </a><br> .large[<b><a href="https://www.pucv.cl/uuaa/site/edic/base/port/labgrs.html">LabGRS</a> | Septiembre 2023</b>] <br> --- class: center,middle background-image: url(data:image/png;base64,#labgrs_logo.png) background-size: 35% --- ## Contenidos .pull-left[ - Visualización de datos espaciales en R - ggplot2 y sf - Creación de mapas con ggplot2 * Creación de datos para mapeo * ggspatial - Creación de mapas con vectores * Ajuste de la escala espacial. * Creación de mapas. * Etiquetas. * Agrupar gráficos. - Creación de mapas con rasters * Preparar datos ráster * Mapa de elevación * Mapa de hillshade * Mapa de elevación más hillshade. * Esquicio dentro de mi mapa. ] .pull-right[ <img src="data:image/png;base64,#https://raw.githubusercontent.com/allisonhorst/stats-illustrations/main/rstats-artwork/r_rollercoaster.png" width="650px"/> © Allison Horst ] --- ## Paquetes para visualización de geodatos -- - Como ya vimos, los geo-datos pueden ser graficados de forma directa empleando la función **plot()** y puede mejorarse con algunos parámetros adicionales. -- - Sin embargo, existen librerías que permiten mejorar la representación tanto estática como dinámica de la información espacial. Algunas de estas librerías son: -- * [**ggplot2**](https://CRAN.R-project.org/package=ggplot2) para creación de gráficos y mapas empleando gramática de gráficos * [**tmap**](https://CRAN.R-project.org/package=tmap) elaboración de mapas temáticos en base a gramática de gráficos * [**rasterVis**](https://CRAN.R-project.org/package=rasterVis) complemento de **raster** y **terra** para visualizaciones mejoradas * [**mapsf**](https://CRAN.R-project.org/package=mapsf) creación de mapas temáticos * [**leaflet**](https://CRAN.R-project.org/package=leaflet) creación de mapas interactivos * etc... --- ## Mas de 15 años de mapas y gráficos con ggplot - El 10 de junio de 2007, el estadístico y desarrollador Hadley Wickham lanzó oficialmente ggplot2, un sistema de elaboración de gráficos para el lenguaje de programación estadístico de R. Esto cambiaría el curso de su vida y el futuro de la visualización de datos. > “Cuando lo creé, esperaba que tal vez mil personas lo usaran”, dijo Wickham a Quartz. “En ese momento, eso parecía un número increíblemente grande”. - Solo en los últimos cinco años, ggplot2 se ha descargado más de 10 millones de veces, con más de 400 000 descargas en el mes anterior a la publicación de este artículo (2017). Los científicos de datos de las principales empresas tecnológicas, el gobierno de EE. UU. y los periodistas de publicaciones como el New York Times utilizan el programa para analizar y presentar datos. Al igual que R, ggplot2 es gratuito y de código abierto. --- ## Prepara la informacion. ```r manzanas <- read_sf('manzanas_maule_utm.shp') # Leer archivo de manzanas censales Maule. resumen_manz <- manzanas %>% st_drop_geometry() %>% group_by(COMUNA) %>% summarise(TOTAL = n()) ``` - Crear un grafico de barras de la cantidad de poblacion por comuna en la región del Maule. ```r ggplot(resumen_manz, aes(x = COMUNA, y = TOTAL))+ # Resumen poblacion geom_bar(stat = "identity")+ # tipo de grafico "bar" de barra theme(axis.text.x=element_text(color = "black", # color del texto size=5, angle=45, vjust=.35,hjust=0.35)) # Ajuste de los bordes y separación ``` --- <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-3-1.png" width="100%" /> --- ## ggplot2 y sf -- - Gracias a la estructura con que son leídos nuestros archivos vectoriales con sf, podemos fácilmente graficar empleando ggplot como soporte gráfico empleando **geom_sf()**. -- - Cargue la capa **Manzanas_Maule.shp** y filtre una comuna
--- ```r ggplot() + geom_sf(data = curico) # carga la capa por defecto ``` <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-6-1.png" width="100%" style="display: block; margin: auto;" /> --- ## Ajustar la escala de trabajo. - Podemos también ajustar la escala de visualización empleando **coord_sf()**. ```r ggplot() + geom_sf(data = curico, colour = 'black', size = 0.2)+ #crea el lienzo para el gráfico coord_sf(xlim = c(291825.286, 299711.669), # extent de longitud ylim = c(6128934.212, 6124211.552), # extent de latitud expand = F) # asegurar la extensión ``` -- - Para ver más parámetros de **geom_sf()** recuerde usar `?geom_sf` --- <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-8-1.png" width="100%" style="display: block; margin: auto;" /> --- ## Preparación de datos - Para poder construir una mejor visualización, crearemos una capa nueva que disponga de una columna de nombre **AREA_HA** y el campo **personas**. -- - Por defecto **st_area()** calcula la superficie en metros, por lo cual convertiremos de forma directa a Hectareas. -- ```r curico_densidad <- curico %>% select(personas) %>% # seleccionar campo de interés mutate(AREA_HA = as.numeric(st_area(.)/10000), # cálculo de área DENSIDAD = personas/AREA_HA) # densidad por manzana ```
--- ## Creación de un mapa con ggplot. -- - Con la información ya creada, prepararemos nuestro mapa de densidad por manzanas ```r ghp <- ggplot() + geom_sf(data = curico_densidad, # Crea el lienzo para el gráfico aes(fill = DENSIDAD), # Selección campo que contiene datos colour = 'black', # Color de las líneas size = 0.2) + # Tamaño de la línea coord_sf(xlim = c(291825.286, 299711.669), # Extent de longitud ylim = c(6128934.212, 6124211.552), # Extent de latitud expand = F) + # Asegurar la extensión scale_fill_viridis_c(trans = 'sqrt') + # Paleta de colores con conversión de valores theme_bw() # Cambio por un tema más simple ghp ``` --- <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-12-1.png" width="100%" style="display: block; margin: auto;" /> --- ## Complementando con ggspatial -- - Para finalizar, usaremos [ggspatial](https://CRAN.R-project.org/package=ggspatial) que presenta varias funciones de fácil uso para elaboración rápida de figuras. -- - Instale la librería empleando `install.packages('ggspatial')` y cárguela con `library(ggspatial)` ```r ghp + annotation_scale(location = "br", # escala width_hint = 0.2, bar_cols = c("white"), # escala style = "ticks", text_col = "white", line_col = "white") + # escala annotation_north_arrow(location = "tl", # flecha norte which_north = "true", # flecha norte height = unit(1,'cm'), # flecha norte width = unit(1,'cm'), # flecha norte. style = north_arrow_fancy_orienteering(text_col = 'white', # flecha norte. line_col = 'white',fill = 'white')) + # flecha norte. theme_bw() + ggtitle("Densidad Poblacional Curico") + #titulo mapa subtitle = "(densidad de habitantes por Hectarea)") + # subtitulo mapa theme(panel.border = element_rect(fill = NA, # borde size = 1.5, colour = "deepskyblue")) # borde ghp ``` --- <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-14-1.png" width="100%" style="display: block; margin: auto;" /> --- ## Etiquetado dentro de un mapa. -- - ggplot permite crear etiquetas simples y complejas para la visualizacion. Para el caso de los poligonos, debemos extraer la coordenada X e Y. para esto usaremos la funcion **st_centroid()** ```r comunas <- st_read("Comunas_Maule.shp") ``` ``` ## Reading layer `Comunas_Maule' from data source ## `E:\Gabriel_Castro_LABGRS\07_DIPLOMADO_LABGRS_2023\clase visualizacion\Comunas_Maule.shp' ## using driver `ESRI Shapefile' ## Simple feature collection with 30 features and 7 fields ## Geometry type: POLYGON ## Dimension: XY ## Bounding box: xmin: 158631.7 ymin: 5953194 xmax: 381493.9 ymax: 6157753 ## Projected CRS: WGS 84 / UTM zone 19S ``` ```r centroid_com <- comunas %>% st_centroid() %>% # calculo centroides st_coordinates() # extraer coordenadas X e Y comunas_centroid <- comunas %>% cbind(centroid_com) # unir las coordenadas a mi shp de comunas ``` --- ## Etiquetado dentro de un mapa. -- - Creemos un mapa con la superficie de las comunas del Maule aplicando cambios a la grilla, nombres de los ejes y etiquetando los nombres de cada comuna en la región. ```r gworld <- ggplot(data = comunas_centroid) + # Tabla centroides geom_sf(aes(fill = SUPERFICIE)) + # Superficie m2 Comunas geom_rect(xmin = 295920, xmax = 305000, # Xlim rectangulo ymin = 6133595, ymax = 6122779, # Ylim rectangulo fill = NA, colour = "red", # color rectangulo size = 1) + # tamaño scale_fill_viridis_c(option = "G", # paleta de colores name = "Superficie m²") + # nombre leyenda geom_text(data = comunas_centroid, # etiqueta centroide aes(X,Y, label = COMUNA), # tabla centroides size = 1.5, colour = "white", # color y tamaño name = "Superficie m²") + # # nombre leyenda theme(panel.grid.major = # grilla element_line(color = gray(.5), # color y forma grilla linetype = "dashed", size = 0.5), # estilo grilla panel.background = # fondo del mapa element_rect(fill ="aliceblue"), # color fondo panel.border = element_rect((fill = NA))) # bordes del mapa gworld ``` --- <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-17-1.png" width="100%" style="display: block; margin: auto;" /> --- ## Visualizacion en la misma ventana. - visualizar usando **plot_grid**. Podemos modificar el tamaño de los plots, las columnas que deseamos usar al igual que las filas. ```r plot_grid(gworld, g, nrow = 1, ncol = 2, rel_widths = c(3, 3)) ``` <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-18-1.png" width="100%" style="display: block; margin: auto;" /> ```r # modificar el tamañano de ambos graficos. ``` --- ## Visualizacion en conjunto - visualizar usando la libreria **patchwork**. Mas rapida, ajuste de plots automatico. ```r gworld + g # suma de graficos hacia la derecha. ``` <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-19-1.png" width="100%" style="display: block; margin: auto;" /> ```r # Operador / permite colocar graficos debajo. # Mas informacion ?patchwork ``` --- --- ## Tidyterra - La librería Tidyterra permite al usuario utilizar funciones de Tidyverse sobre objectos de tipo spatvector o spatraster añadiendo funciones para su visualización en ggplot2. - La librería cuenta con diferentes paletas de colores para operar sobre vectores o rasters siendo **scale_fill_wiki()** y **scale_fill_hypso()** las más utilizadas. - **NOTA**: Tidyterra trabaja de forma segura cuando nuestro ráster posee menos de 10 millones de pixeles (10e6). En caso de tener un ráster que exceda esta cantidad, se aplicara un remuestreo automático para obtener un numero de celdas <10e6. <center> <img style="float: width="600" height="250";" src="tidyterra.JPG"> <center> --- ## Creación de mapas a partir de rasters con ggplot2. - a partir de la libreria tidyterra, podemos incorporar objetos de tipo spatraster en la visualización de ggplot. ```r # map ggplot() + geom_spatraster(data = mdt) + # geom_spatraster (spartura) scale_fill_hypso_tint_c(breaks = c(140, 250, 500, 1000, # paleta de elevación o batimetría 1500, 2000, 2500, # rango de valores leyenda 3000, 3500, 4000)) + guides(fill = guide_colorsteps(barwidth = 20, # tamaño barra elevación leyenda barheight = .5, title.position = "right")) + # posición titulo leyenda labs(fill = "m.s.n.m") + coord_sf() + theme_void() + # nombre leyenda theme(legend.position = "bottom") + # posición leyenda ggtitle("Densidad Poblacional Talca") + # nombre Mapa theme(panel.border = element_rect(fill = NA, size = 1)) # Borde Mapa ``` --- <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-22-1.png" width="100%" style="display: block; margin: auto;" /> --- ## Creacion de mapas a partir de rasters con ggplot2. - Para mejorar la visualizacion de nuestro mapa de elevación, podemos crear un mapa de sombras <b>(Hillshade)</b> para contrastar el terreno de mejor manera. ```r sl <- terrain(mdt, "slope", unit = "radians") plot(sl) ``` <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-23-1.png" width="100%" style="display: block; margin: auto;" /> --- # Orientacion o Aspecto del DEM. ```r asp <- terrain(mdt, "aspect", unit = "radians") plot(asp) ``` <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-24-1.png" width="100%" style="display: block; margin: auto;" /> --- # Hillshade. ```r hill_single <- shade(sl, asp, angle = 45, direction = 300,normalize= TRUE) # final hillshade plot(hill_single, col = grey(1:100/100)) ``` <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-25-1.png" width="100%" style="display: block; margin: auto;" /> --- ## Mapa de elevación mas Hillshade. - Una vez creado nuestro hillshade podemos crear nuestro mapa de elevación final. ```r hilldf_single <- hill_single ``` ```r terrain_map <- ggplot() + geom_spatraster(data = hilldf_single, show.legend = FALSE) + # Sacar la leyenda de sombras scale_fill_distiller("moon_hypso") + new_scale_fill() + # paleta Hillshade geom_spatraster(data = mdt, alpha = .7) + # Data elevación scale_fill_hypso_tint_c(breaks = # paleta c(180,250,500,1000,1500,2000,2500,3000,3500,4000)) # intervalos de elevación ``` --- ```r terrain_map + guides(fill = guide_colorsteps(barwidth = .5, # agregar barra de leyenda barheight = 15, # altura barra leyenda title.position = "top")) + # posicion titulo leyenda annotation_scale(location = "br", # posición escala grafica width_hint = 0.5, bar_cols = c("black"), style = "ticks", # tipo de escala text_col = "black", line_col = "black") + # colores escala annotation_north_arrow(location = "tr", # norte height = unit(1,'cm'),width = unit(1,'cm'), # propiedades norte style = north_arrow_fancy_orienteering(text_col = 'black', # orientación norte line_col = 'black',fill = 'white')) + labs(x = "UTM este", # Xlab etiqueta eje y = "UTM norte") + # Ylab etiqueta eje ggtitle("Mapa de elevación comuna Curicó") + coord_sf() + # Titulo Mapa labs(fill = "m.s.n.m") + theme_void() + theme(panel.border = element_rect(fill = NA, size = 1)) # Fondo de mapa y titulo leyenda terrain_map ``` --- <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-29-1.png" width="100%" style="display: block; margin: auto;" /> --- ## Crear un Esquicio dentro de mi mapa. - Para esto debemos editar nuestro mapa inicial de superficie de las comunas de la región del Maule. - Esto con la finalidad de señalar de forma clara, la zona en la que nos encontramos trabajando. ```r datos_curico <- comunas %>% filter(COMUNA == "Curicó") datos_grises <- comunas %>% filter(COMUNA != "Curicó") ``` <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-31-1.png" width="100%" style="display: block; margin: auto;" /> --- ```r # Crear el mapa con ggplot2 esquicio <- ggplot() + geom_sf(data = datos_grises, fill = "grey", # Comunas Maule color = "black", size = 0.01, alpha = 0.4) + # color poligonos, tamaño, opacidad geom_sf(data = datos_curico, fill = "red", # Comuna de Curicó color = "black", size = 0.01, alpha = 0.7) + # color poligonos, tamaño, opacidad labs(title = "Región del Maule") + # titulo Mapa theme(panel.grid.major = # Grilla del mapa element_line(color = gray(.1, alpha = 0.1), # tamaño opacidad de la grilla linetype = "solid"), # tipo de linea panel.background = element_rect(fill ="aliceblue"), # color de fondo panel.border = element_rect((fill = NA))) + # borde theme(axis.text.x=element_blank(), # eliminar texto eje X axis.ticks.x=element_blank(), # eliminar coords eje X axis.text.y=element_blank(), # eliminar texto eje Y axis.ticks.y=element_blank()) # eliminarcoords eje y esquicio ``` --- <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-33-1.png" width="100%" style="display: block; margin: auto;" /> --- ## Unir el esquicio con mi mapa de elevación. ```r ggdraw(terrain_map) + draw_plot({ esquicio + # agregar el esquicio labs(title = "Región del Maule") + # titulo del mapa theme(plot.title = element_text(size = 8)) + # tamaño titulo coord_sf(xlim = c(158631.681054539, # extension 381493.92423123), ylim = c(5953193.82059836, 6157752.73594698), expand = FALSE) + # asegurar la extensión theme(legend.position = "none")}, # sacar la leyenda x = 0.15, # distancia eje X y = 0.105, # distancia eje y width = 0.30, # ancho del esquicio height = 0.35) # alto del esquicio ``` --- <img src="data:image/png;base64,#clase_ggplot2_files/figure-html/unnamed-chunk-35-1.png" width="100%" style="display: block; margin: auto;" /> --- ## Bibliografía complementaria - [Lovelace, R., Nowosad, J., & Muenchow, J. (2022). Geocomputation with R. Chapman and Hall/CRC.](https://geocompr.robinlovelace.net/index.html) - [Hadley Wickham (2009). ggplot2: Elegant Graphics for Data Analysis](https://ggplot2-book.org/) - [Yan Holtz's (2018). The R Graph Gallery](https://r-graph-gallery.com/) - [Edzer Pebesma r-spatial (2018). Drawing beautiful maps programmatically with R, sf and ggplot2 — Part 1: Basics](https://r-spatial.org/r/2018/10/25/ggplot2-sf.html) - [Diego Hernan gómez R-CRAN (2023).Package ‘tidyterra’](https://github.com/dieghernan/tidyterra) - [Dan Kopf ggplot2—The code powering all those excellent charts is 10 years old](https://qz.com/1007328/all-hail-ggplot2-the-code-powering-all-those-excellent-charts-is-10-years-old) --- class: inverse middle 